<script setup lang="ts" name="CanvasRuler">
import { drawCanvasRuler } from './utils'
import { storeToRefs } from 'pinia'
import { useSystemConfigStore } from '@/store/storage/systemConfigStore'
const systemConfigStore = useSystemConfigStore()
const { systemConfig } = storeToRefs(systemConfigStore)

const emits = defineEmits(['onAddLine', 'update:showIndicator', 'update:valueNum'])

const props = defineProps({
  valueNum: {
    type: Number,
    required: true
  },
  scale: {
    type: Number,
    required: true
  },
  ratio: {
    type: Number
  },
  start: {
    type: Number,
    required: true
  },
  width: {
    type: Number,
    required: true
  },
  height: {
    type: Number,
    required: true
  },
  shadowStart: {
    type: Number
  },
  shadowLength: {
    type: Number
  },
  vertical: {
    type: Boolean
  }
})

const state = reactive({
  canvasContext: null
})
let ratioValue = 1
const canvas = ref(null)

const initCanvasRef = () => {
  state.canvasContext = canvas.value && canvas.value.getContext('2d')
}

const updateCanvasContext = (ratio: number) => {
  if (canvas.value) {
    // 比例宽高
    canvas.value.width = props.width! * ratio!
    canvas.value.height = props.height! * ratio!
    const ctx = state.canvasContext
    if (ctx) {
      ctx.font = `${12 * ratio!}px -apple-system,
            "Helvetica Neue", ".SFNSText-Regular",
            "SF UI Text", Arial, "PingFang SC", "Hiragino Sans GB",
            "Microsoft YaHei", "WenQuanYi Zen Hei", sans-serif`
      ctx.lineWidth = 1
      ctx.textBaseline = 'middle'
    }
  }
}

const drawRuler = (ratio: number) => {
  const options = {
    scale: props.scale!,
    width: props.width!,
    height: props.height!,
    ratio: ratio
  }

  if (state.canvasContext) {
    drawCanvasRuler(
      systemConfig,
      state.canvasContext,
      props.start!,
      props.shadowStart!,
      props.shadowLength!,
      options,
      !props.vertical
    )
  }
}

watch(
  () => props.start,
  () => drawRuler(ratioValue)
)

watch(
  [() => props.width, () => props.height],
  () => {
    updateCanvasContext(ratioValue)
    drawRuler(ratioValue)
  }
)

const handle = (e: MouseEvent, key: string) => {
  const getValueByOffset = (offset: number, start: number, scale: number) =>
    Math.round(start + offset / scale)
  const offset = props.vertical ? e.offsetY : e.offsetX
  const value = getValueByOffset(offset, props.start!, props.scale!)
  switch (key) {
    case 'click':
      emits('onAddLine', value)
      break
    case 'enter':
      emits('update:valueNum', value)
      emits('update:showIndicator', true)
      break
    default:
      emits('update:valueNum', value)
      break
  }
}

const hideIndicator = () => {
  emits('update:showIndicator', false)
}
onMounted(() => {
  ratioValue = props.ratio || window.devicePixelRatio || 1
  initCanvasRef()
  updateCanvasContext(ratioValue)
  drawRuler(ratioValue)
})
</script>

<template>
  <canvas ref="canvas" class="ruler" @click="handle($event, 'click')" @mouseenter="handle($event, 'enter')" @mousemove="handle($event, 'move')" @mouseleave="hideIndicator" />
</template>

<style scoped lang="scss">
.ruler {
  width: 100%;
  height: 100%;
  pointer-events: auto;
}
</style>
